package com.adv.io;

import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;
import java.util.*;

/**
 * 10:baidu nio和io的区别,写一个nio的例子 1：传统的IO特点 它的各种流是阻塞的。
 * 单线程的情况下，只能存在一个客户端。以为档一个线程调用读写的方法的时候，会被阻塞，直到有一些数据被读取或者数据被完全写入。 它是面向流的。
 * 每次是从流中读取一个后者多个字节，直到所有的字节被读完。没有缓冲区，不能前后移动流中的数据。
 * serverSocket和socket都是阻塞式的，因此一旦有大规模的并发行为，而每一个访问都会开启一个新线程。 2：NIO
 * 是为了弥补IO的不足而诞生的，性特性为：非阻塞I/O，选择器，缓冲以及管道。管道（Channel），缓冲（Buffer） ，选择器（
 * Selector）是其主要特征：
 * 
 * buffer：因为NIO是基于缓冲的，所以buffer是最底层的必要类，这也是IO和NIO的根本不同，虽然stream等有buffer开头的扩展类，但只是流的包装类，还是从流读到缓冲区，而NIO却是直接读到buffer中进行操作。
 * 
 * channel：类似于IO的stream，但是不同的是除了FileChannel，其他的channel都能以非阻塞状态运行。FileChannel执行的是文件的操作，可以直接DMA操作内存而不依赖于CPU。其他比如socketchannel就可以在数据准备好时才进行调用。
 * 
 * selector：用于分发请求到不同的channel，这样才能确保channel不处于阻塞状态就可以收发消息。
 * 
 * 并且在NIO中，数据读取到一个它稍后处理的缓冲区，需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是，还需要检查是否该缓冲区中包含所有您需要处理的数据。而且，需确保当更多的数据读入缓冲区时，不要覆盖缓冲区里尚未处理的数据。NIO的buffer可以使用直接内存缓冲区，该缓冲区不在JVM中，性能会比JVM的缓冲区略好，不过会增加相应的垃圾回收的负担，因为JVM缓冲区的性能已经足够好，所以除非在对缓冲有特别要求的地方使用直接缓冲区，尽量使用JVM缓冲。
 * ———————————————— 版权声明：本文为CSDN博主「YanZhenRui」的原创文章，遵循CC 4.0
 * BY-SA版权协议，转载请附上原文出处链接及本声明。
 * 原文链接：https://blog.csdn.net/YanZhenRui/article/details/85009211
 * 
 * @author zhaoyang
 *
 */
public class IO_Work10 {

	public static void main(String[] args) throws Exception {
		// 得到文件输入流
		FileInputStream fileInputStream = new FileInputStream(new File("D:\\text.txt"));
		// 得到输入Channel通道
		FileChannel inChannel = fileInputStream.getChannel();
		// 得到bytebuffer缓冲区
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		// 得到输出流
		FileOutputStream fileOutputStream = new FileOutputStream("D:\\text3.txt");
		// 得到输出通道
		FileChannel outChanner = fileOutputStream.getChannel();
		int eof = -1;
		// 如果读取到的长度不为-1则缓冲区有数据
		while ((eof = inChannel.read(byteBuffer)) != -1) {
			// 从读模式切换到写模式
			byteBuffer.flip();
			// 写入到指定文件
			outChanner.write(byteBuffer);
			// 清空缓冲区
			byteBuffer.clear();
		}
		// 关闭通道和输入输出流
		outChanner.close();
		fileOutputStream.close();
		inChannel.close();
		fileInputStream.close();
	}
}
